/*
 * 人人信用管理有限公司版权所有.
 * 
 * @Description:
 * 
 * @author: liyuliang
 * 
 * @date: 20 Apr 2017 10:44:16 am
 * 
 * 注意：本内容仅限于人人信用管理有限公司内部传阅，禁止外泄以及用于其他的商业目的.
 */

package com.rrx360.common.util;

import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * 字符串验证
 * 
 * 1.姓名,String类型，（0,15] 汉字，或汉字加点（如，莱丽古丽·阿依吐露汗） 2.手机号码，number类型，11位，1位+【3,4,5,7,8】+9位
 * 3.身份证号校验规则参考蒋杰代码 4.居住地址、单位地址、所有地址，统一100位字符不限类型 5.单位名称：80字符 6.公司名称：80字符 7.支行名称：80字符 8.单位座机（电话）分三段
 * 座机号不为空时，做如下校验：区号3-5字符，座机电话6-8字符，分机号最大6字符，选填 格式：区号-座机电话（-分机号） 9.银行卡号，限定输入数字，长度12-19字符 10.车牌号码，待定
 * 11.金额验证:可正可负,两位小数点
 * 
 * @author yin197
 */
public class Validator {

  private static final Logger logger = LogManager.getLogger();
  // 电话号码验证表达式
  private static Pattern MOBILEPATTERN = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$");
  // 身份证号码验证表达式
  // private static Pattern idCardNumberPattern = Pattern.compile("^\\d{17}(\\d|X)$");
  // 电子邮箱验证表达式
  private static Pattern EMAILPATTERN = Pattern
      .compile("^[a-z0-9]+([._\\-]?[a-z0-9]+)*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$");
  // 中文名字正则表达式,小于15位
  // private static Pattern NAMEPATTERN = Pattern.compile("^[\u4e00-\u9fa5|·]{0,15}$");
  private static Pattern NAMEPATTERN = Pattern.compile("^[一-龥|·]{0,15}$");

  private static final int ADDR_LIMIT_LENGTH = 100;// 居住地址、单位地址、所有地址，统一100位字符不限类型

  private static final int WORK_PLACE_LIMIT = 80;// 单位名称：80字符

  private static final int COMPANY_LIMIT = 80;// 公司名称：80字符

  private static final int BANK_BRANCH_LIMIT = 80;// 支行名称：80字符

  private static final Pattern ELEVENNUMPATTERN = Pattern.compile("^\\d{11}$");

  private static Pattern LANDLINEPATTERN = Pattern.compile("^\\d{3,5}-\\d{6,8}(-\\d{1,6})?$");

  private static Pattern BANKPATTERN = Pattern.compile("^\\d{16,19}$");

  /**
   * 金额正则,可正可负,两位小数点 |([1-9]\\d{0,20})\\.\\d{2}$
   */
  private static Pattern MONEYPARTTERN =
      Pattern.compile("^[-+]?(0|([1-9]\\d{0,20}))(\\.\\d{1,2})?$");

  /**
   * 用于存入 >= ,>,<= ,<
   * 
   * @author yin197
   *
   */
  public static enum Expr {
    GE, GT, LE, LT, EQ
  }

  /**
   * 验证是否为十一位数字
   * 
   * @param realName
   * @return
   */
  public static boolean isElevenNum(String inData) {

    boolean flag = ELEVENNUMPATTERN.matcher(inData).matches();
    if (!flag) {
      logger.debug("参数不是十一位数字!");
    }
    return flag;
  }

  /**
   * 验证是否为中文真名
   * 
   * @param realName
   * @return
   */
  public static boolean isChinaName(String s) {
    if (StringUtils.isEmpty(s)) {
      logger.debug("参数为空!");
      return false;
    }
    if (NAMEPATTERN.matcher(s).matches()) {
      int temp = s.indexOf('·');
      if (temp >= 0) {
        for (int i = temp; i < s.length() && temp >= 0; i = temp) {
          if (i == 0 || i == s.length() - 1 || s.charAt(i + 1) == '·') {
            logger.debug("参数'·'在首尾，或参数中有连续的'·'!");
            return false;
          } else {
            temp++;
            temp = s.indexOf('·', temp);

          }
        }
      }
      return true;

    }
    logger.debug("参数与标准模式不匹配!(标准模式:0,15] 汉字，或汉字加点（如，莱丽古丽·阿依吐露汗）)");
    return false;

  }

  /**
   * 前缀为+86或+0电话号码验证
   * 
   * @param s
   * @return
   */
  public static boolean isChinaMobileNumer(String s) {
    if (s == null || s.length() < 11) {
      logger.debug("参数为null或不没11位!");
      return false;
    }
    if (s.startsWith("+86")) {
      s = s.substring(3);
    } else if (s.startsWith("+0")) {
      s = s.substring(2);
    }

    return isChinaMobileNumber11(s);
  }

  /**
   * 前缀为+86或+0电话号码验证
   * 
   * @param s
   * @return
   */
  public static boolean isChinaMobileNumber11(String s) {
    if (s == null || s.length() < 11) {
      logger.debug("参数为null或不没11位!");
      return false;
    }

    boolean flag = MOBILEPATTERN.matcher(s).matches();
    if (!flag) {
      logger.debug("参数与标准电话模式不匹配（标准模式为：1[3,4,5,7,8]开头）!");
    }
    return flag;
  }

  public static boolean lengthLessOrEqual(String s, int l) {

    if (s == null) {
      logger.debug("参数为null!");
      return false;
    }
    if (s.length() > l) {
      logger.debug("参数长度超过了限制（ " + l + " )长度！");
    }
    return s.length() <= l;
  }

  /**
   * 居住地址、单位地址、所有地址
   * 
   * @param s
   * @return
   */
  public static boolean isAddr(String s) {

    return lengthLessOrEqual(s, ADDR_LIMIT_LENGTH);
  }

  /**
   * 单位名称
   * 
   * @param s
   * @return
   */
  public static boolean isWorkSpace(String s) {

    return lengthLessOrEqual(s, WORK_PLACE_LIMIT);
  }

  /**
   * 公司名称
   * 
   * @param s
   * @return
   */
  public static boolean isCommpany(String s) {

    return lengthLessOrEqual(s, COMPANY_LIMIT);
  }

  /**
   * 支行名称
   * 
   * @param s
   * @return
   */
  public static boolean isBankBranch(String s) {

    return lengthLessOrEqual(s, BANK_BRANCH_LIMIT);
  }

  /**
   * 是否为座机
   * 
   * @param s
   * @return
   */
  public static boolean isLandLineNumber(String s) {
    if (s == null) {
      logger.debug("参数为null!");
      return false;
    }
    if (!LANDLINEPATTERN.matcher(s).matches()) {
      logger.debug("参数格式不正确！（座机号不为空时，做如下校验：区号3-5字符，座机电话6-8字符，分机号最大6字符，选填格式：区号-座机电话（-分机号））");
      return false;
    }
    return true;
  }

  /**
   * 字符串长度在min和max之间
   * 
   * @param s
   * @param min
   * @param max
   * @return
   */
  public static boolean lengthBetween(String s, int min, int max) {
    if (s == null) {
      if (min == 0) {
        return true;
      }
      return false;
    }
    return s.length() >= min && s.length() <= max;
  }

  /**
   * 字符串长度小于等于max
   * 
   * @param s
   * @param max
   * @return
   */
  public static boolean lengthLtOrEq(String s, int max) {
    if (s == null) {
      return true;
    }
    return s.length() <= max;
  }

  /**
   * 字符串长度大于等于min
   * 
   * @param s
   * @param min
   * @return
   */
  public static boolean lengthGtOrEq(String s, int min) {
    if (s == null) {
      if (min == 0) {
        return true;
      }
      return false;
    }
    return s.length() >= min;
  }

  public static boolean lengthEq(String s, int length) {
    if (s == null) {
      if (length == 0) {
        return true;
      }
      return false;
    }
    return s.length() == length;
  }

  public static boolean isNotNull(Object o) {
    return o != null;
  }

  /**
   * 是否为生日格式
   * 
   * @param birthday
   * @return
   */
  public static boolean isBirthdayForm(String birthday) {
    if (birthday != null) {
      String str = "^\\d{4}-(0|1)\\d-(0|1|2|3)\\d$";
      if (birthday.matches(str)) {
        return true;
      }
    }
    return false;
  }

  /**
   * 字符串是否为email
   * 
   * @param email
   * @return
   */
  public static boolean isEmail(String email) {
    if (email == null) {
      logger.debug("参数为null!");
      return false;
    }
    if (!EMAILPATTERN.matcher(email).matches()) {
      logger.debug("参数格式不正确!");
      return false;
    }
    return true;
  }

  /**
   * 验证车牌号
   * 
   * @param carNumber
   * @return
   */
  public static boolean isCarNumber(String carNumber) {
    if (carNumber != null) {
      // String str = "^[\u4e00-\u9fa5][A-Z][A-Z_0-9]{5}$"; 
      String str = "^[一-龥][A-Z][A-Z_0-9]{5}$";
      if (carNumber.matches(str)) {
        return true;
      }
    }
    return false;
  }

  /**
   * 是否为银行卡号
   * 
   * @param bankCardNumber
   * @return
   */
  public static boolean isBankCardNumber(String s) {
    if (s == null) {
      logger.debug("参数为null!");
    }
    if (!BANKPATTERN.matcher(s).matches()) {
      logger.debug("格式不正确（银行卡号，限定输入数字，长度12-19字符）");
      return false;
    }
    return true;
  }

  /**
   * 是否为身份证号
   * 
   * @param idCardNumber
   * @return
   */
  public static boolean isIdCardNumber(String idCardNumber) {

    return IdCardValidator.isValidatedAllIdcard(idCardNumber);
  }

  public static boolean isMoney(String money) {
    if (isNotNull(money) && MONEYPARTTERN.matcher(money).matches()) {
      return true;
    }
    return false;
  }

  public static boolean isMoney(String money, Expr expr, double value) {
    if (isNotNull(money) && MONEYPARTTERN.matcher(money).matches()) {
      // GE,GT,LE,LT,EQ
      switch (expr.ordinal()) {
        case 0:
          return Double.valueOf(money) >= value;
        case 1:
          return Double.valueOf(money) > value;
        case 2:
          return Double.valueOf(money) <= value;
        case 3:
          return Double.valueOf(money) < value;
        case 4:
          return Math.abs(Double.valueOf(money) - value) < 0.000001;
        default:
          throw new RuntimeException("不存在的运算符");
      }
    }

    return false;
  }

  // public static int getInt(String idCardNumber,int i,int j){
  // return Integer.parseInt(idCardNumber.substring(i,j));
  // }
  //
  // public static boolean isInt(String number){
  // String str = "[1-9]+\\d*";
  // if(number.matches(str)){
  // return true;
  // }
  // return false;
  // }

  // public static boolean valueBetween(long number,long start,long end){
  // return number >= start && number <= end;
  // }

  public static void main(String[] args) {
    // System.out.println(isEmail("liyuliang_12?33.1233@123.com.cn"));
    // System.out.println(isIdCardNumber("14242287040701"));
    // System.out.println(isLandLineNumber("123-44524545-3333"));
    // System.out.println(isChinaName("中··国中"));
    // System.out.println(isEmail("aaa.aa.@aaa.com"));
    // System.out.println(isElevenNum("1111111111"));
    // System.out.println(isIdCardNumber("142422198704073013"));
    // System.out.println(isBankBranch("sdsfsfsssssssssssssssssss
    // sssssssssssssssssssssssssssssssssssssss
    // sssssssssssssssssssssssssssssssssss"));
    // 金额测试
    // System.out.println(isMoney("1"));
    // System.out.println(isMoney("123312341"));
    // System.out.println(isMoney("-1"));
    // System.out.println(isMoney("-0.12"));
    // System.out.println(isMoney("-0.12"));
    // System.out.println(isMoney("0.00"));
    // System.out.println(isMoney("-0.00"));
    // System.out.println(isMoney("-0.0"));
    // System.out.println(isMoney("-0.0"));
    // System.out.println(isMoney("+.0"));
    // System.out.println(isMoney("+.0"));
    validMnoneyTest();
  }

  private static void validMnoneyTest() {
    // System.out.println(isMoney("11",Expr.GE,11));
    // System.out.println(isMoney("11",Expr.GT,11));
    // System.out.println(isMoney("11",Expr.LE,11));
    // System.out.println(isMoney("11",Expr.LT,11));
    // System.out.println(isMoney("11",Expr.EQ,11));

  }

}
